package com.example.demo.filter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author ListJiang
 * @since 2021/10/19
 * description
 */
public class AuthenticationFilter extends OncePerRequestFilter {
    public static final String TOKEN_KEY = "token-key:";
    private static final Log log = LogFactory.getLog(AuthenticationFilter.class);

    private final AntPathRequestMatcher antPathRequestMatcher = new AntPathRequestMatcher("/**");

    private final RedisTemplate redisTemplate;


    public AuthenticationFilter(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        if (antPathRequestMatcher.matches(request)) {
            log.info("自定义认证校验...");
            String authorization = request.getHeader("Authorization");
            // 登录成功校验逻辑
            if (StringUtils.hasText(authorization)) {
                String authToken = authorization.substring(6).trim();
                if (redisTemplate.hasKey(TOKEN_KEY + authToken)) {
                    Object o = redisTemplate.opsForValue().get(TOKEN_KEY + authToken);
                    if (o instanceof Authentication) {
                        SecurityContextHolder.getContext().setAuthentication((Authentication) o);
                    }
                } else {
                    SecurityContextHolder.clearContext();
                }
            }
        }

        chain.doFilter(request, response);
    }
}